#include "common/asyc/threadpool.h"
#include <QDebug>

using namespace thread_pool_data;

ThreadPool::ThreadPool()
{
    _init();
    qDebug() << "threadpool constructor..";
}

QRunnable *ThreadPool::getOneTask()
{
    return m_taskQueue.dequeue();
}

int ThreadPool::taskSize()
{
    return m_taskQueue.queueSize();
}

bool ThreadPool::isEmpty()
{
    return m_taskQueue.isEmpty();
}

void ThreadPool::runTask()
{
    if (!_hasOk())return;
    //.
    // qDebug() << "threadpool thread id:" << QThread::currentThreadId();
    while (!isEmpty())
    {
        auto ptask = getOneTask();
        if (ptask != nullptr)
        {
            TaskBase* baseTask = static_cast<TaskBase*>(ptask);
            if (baseTask != nullptr)
            {
                // 每次提交任务前，计数 +1
                m_runningTasks.fetchAndAddOrdered(1);

                qDebug() << QString("[p%1]task priority:%2")
                            .arg(baseTask->id()).arg(baseTask->priority());
                m_threadPool->start(ptask/*, baseTask->priority()*/);
                // qDebug() << "[size]queue size:" << taskSize();
                // qDebug() << "[e]isEmpty:" << (isEmpty() ? "0" : "1");
            }
        }
    }
}

ThreadPool::~ThreadPool()
{
    if (_hasOk())
    {
        m_threadPool->clear();
        m_threadPool->waitForDone(maxWaitQuitTime);
    }
    qDebug() << "threadpool destructor.";
}

void ThreadPool::taskFinished(int id, const QVariant &v)
{
    Q_UNUSED(v)
    qDebug() << "call taskFinished: " << id;
    _exit();
}

void ThreadPool::_init()
{
    m_threadPool = QThreadPool::globalInstance();
    Q_ASSERT(m_threadPool);
    // 根据CPU核心数动态设置
    int idealCount = QThread::idealThreadCount();

    m_threadPool->setMaxThreadCount(ioIntensive ? (baseThreadSize * idealCount) :
                                        qMax(baseThreadSize, idealCount * 2));

    connect(this, &ThreadPool::finished, this, &ThreadPool::taskFinished);
}

bool ThreadPool::_hasOk()
{
    return m_threadPool != nullptr;
}

void ThreadPool::_exit()
{
    int oldCount = m_runningTasks.fetchAndAddOrdered(-1);
    int newCount = oldCount - 1;

    qDebug() << "One task finished. Remaining:" << newCount;

    if (newCount == 0) {
        emit taskExit();  // 所有任务完成
    }
}
